package org.gas.barapraja.proc;

import java.io.IOException;

import org.apache.log4j.Logger;

import com.logica.smpp.Connection;
import com.logica.smpp.Data;
import com.logica.smpp.Receiver;
import com.logica.smpp.SmppObject;
import com.logica.smpp.Transmitter;
import com.logica.smpp.pdu.PDU;
import com.logica.smpp.pdu.Request;
import com.logica.smpp.pdu.Response;
import com.logica.smpp.pdu.ValueNotSetException;

public class GasSmscSession extends SmppObject implements Runnable{
	
	private static Logger logger=Logger.getLogger(GasSmscSession.class);
	/**
	 * 
	 */
	private Receiver receiver;
	
	/**
	 * 
	 */
	private Transmitter transmitter;
	
	/**
	 * 
	 */
	private Connection connection;
	
	/**
	 * 
	 */
	private PduProcessor pduProcessor;
	
	/**
	 * 
	 */
	private long receiveTimeout=Data.RECEIVER_TIMEOUT;
	
	/**
	 * 
	 */
	private boolean keepReceiving=true;
	
	/**
	 * 
	 */
	static boolean isReceiving=false;
	
	public GasSmscSession(Connection connection){
		this.connection=connection;
		this.transmitter=new Transmitter(connection);
		this.receiver=new Receiver(transmitter, connection);
	}
	
	public void sendPdu(PDU pdu){
		logger.info("session start to sending pdu over transmitter..");
		try {
			transmitter.send(pdu);
			logger.info("pdu sent over transmitter...");
		} catch (ValueNotSetException e) {
			logger.error("failed to sending pdu..");
			e.printStackTrace();
		} catch (IOException e) {
			logger.error("failed to sending pdu...");
			e.printStackTrace();
		}
	}
	
	public void stop(){
		logger.info("session stop");
		keepReceiving=false;
	}

	public void run() {
		PDU pdu=null;
		logger.info("start receiver");
		receiver.start();
		isReceiving=true;
		try{
			while(keepReceiving){
				logger.info("try to receive pdu...");
				try{
					pdu=receiver.receive(getReceiveTimeout());
				}catch(Exception e){
					logger.error("failed to receive pdu..");
				}
				if(pdu!=null){
					if(pdu.isRequest()){
						logger.info("received request pdu: "+pdu.debugString());
						pduProcessor.clientRequest((Request)pdu);
					}else if(pdu.isResponse()){
						logger.info("received response pdu: "+pdu.debugString());
						pduProcessor.clientResponse((Response)pdu);
					}else{
						logger.info("standby to receive pdu");
					}
				}
			}
		}finally{
			isReceiving=false;
		}
		logger.info("stoping receiver");
		receiver.stop();
		logger.info("exiting pdu processor: "+pduProcessor.getProcessName());
		pduProcessor.stop();
		try{
			logger.info("trying to close the connection..");
			connection.close();
		}catch(IOException e){
			logger.error("closing connection failed..");
			e.printStackTrace();
		}
		
	}

	public long getReceiveTimeout() {
		return receiveTimeout;
	}

	public PduProcessor getPduProcessor() {
		return pduProcessor;
	}

	public void setPduProcessor(PduProcessor pduProcessor) {
		this.pduProcessor = pduProcessor;
	}
	
	

}
